package com.ofek.base.db;

import java.lang.reflect.Field;

public class Column {
	private final String name;
	private final String extendedtype;
	private final String sqltype;
	private final boolean isKey;
	private final Field field;
	private final boolean isAutoIncrement;
	private final boolean isNullable;
	private final Class references;
	private final String referenceField;
	
	public Column(final Field f) {
		field = f;
		field.setAccessible(true);
		extendedtype = getExtendedType(f);
		sqltype = getType(f);
		name = f.getName();
		final DataField annotation = f.getAnnotation(DataField.class);
		isKey = annotation.isKey();
		isAutoIncrement = annotation.isAutoIncrement();
		isNullable = annotation.isNullable();
		references = annotation.references();
		referenceField = annotation.referenceField();
	}
	
	private static String getType(final Field f) {
		final Class<?> type = f.getType();
		if (type.equals(Long.class) || type.equals(long.class)) return "long";
		if (type.equals(Integer.class) || type.equals(int.class) || type.equals(Boolean.class) || type.equals(boolean.class)) return "int";
		if (type.equals(Float.class) || type.equals(float.class) || type.equals(Double.class) || type.equals(double.class)) return "real";
		if (type.equals(String.class)) return "text";
		throw new IllegalArgumentException("type not suppurted : "+type);
	}
	private static String getExtendedType(final Field f) {
		final Class<?> type = f.getType();
		if (type.equals(Boolean.class) || type.equals(boolean.class)) return "boolean";
		else return getType(f);
	}
	
	public String getName() {
		return name;
	}

	public String getType() {
		return extendedtype;
	}
	
	@Override
	public String toString() {
		return name + " " + (isKey && isAutoIncrement ? "INTEGER" : sqltype) + (isNullable ? "" : " NOT NULL")+ (references!=DataField.EmptyClass.class? " REFERENCES "+references.getSimpleName()+"("+referenceField+") ON DELETE CASCADE " : "");
	}

	public boolean isKey() {
		return isKey;
	}

	public void set(final Object object, final Object value) {
		try {
			field.set(object, value);
		} catch (final Exception e) {
			e.printStackTrace();
		}
	}
	public Object get(final Object object) {
		try {
			return field.get(object);
		} catch (final Exception e) {
			e.printStackTrace();
		} 
		return null;
	}

	public Class<?> getJavaType() {
		return field.getType();
	}

	public boolean isAutoIncrement() {
		return isAutoIncrement;
	}

}
